package com.tanhua.dubbo.server.api;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import com.alibaba.dubbo.config.annotation.Service;
import com.tanhua.dubbo.server.pojo.UserLike;
import com.tanhua.dubbo.server.vo.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Service(version = "1.0.0")
@Slf4j
public class UserLikeApiImpl implements UserLikeApi {
    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    public static final String LIKE_REDIS_KEY_PREFIX = "USER_LIKE_";
    public static final String NOT_LIKE_REDIS_KEY_PREFIX = "USER_NOT_LIKE_";
    //喜欢
    @Override
    public Boolean likeUser(Long userId, Long likeUserId) {
        //查询是否有记录

        if(this.isLike(userId, likeUserId)){
            return false;
        }
      /*  Query query=Query.query(Criteria.where("userId").is(userId)
                                .and("likeUserId").is(likeUserId));
        UserLike userLike = this.mongoTemplate.findOne(query, UserLike.class);

        if (ObjectUtil.isNotEmpty(userLike)) {
            //不为空存储失败 返回false
            return  false;
        }*/
        //为空,封装存入数据库
        UserLike userLike=null;
        try {
            userLike=new UserLike();
            userLike.setId(ObjectId.get());
            userLike.setCreated(System.currentTimeMillis());
            userLike.setLikeUserId(likeUserId);
            userLike.setUserId(userId);
            this.mongoTemplate.save(userLike);
            //保存redis数据库
            String likeRedisKey=getUserLikeKey(userId);
            String hashKey= Convert.toStr(likeUserId);
            this.redisTemplate.opsForHash().put(likeRedisKey,hashKey,"1");

            //判断，喜欢的用户是否在不喜欢的列表中，如果在，就需要删除数据
            if (this.isNotLike(userId,likeUserId)) {
                String notLikeRedisKey=getUserNotLikeRedisKey(userId);
                this.redisTemplate.opsForHash().delete(notLikeRedisKey,hashKey);
            }
            return true;
        } catch (Exception e) {
            log.error("喜欢数据存储失败userId="+userId+",likeUserId="+likeUserId,e);
        }
        return false;
    }

    private String getUserNotLikeRedisKey(Long userId) {
        return NOT_LIKE_REDIS_KEY_PREFIX+userId;
    }

    private String getUserLikeKey(Long userId) {
        return LIKE_REDIS_KEY_PREFIX+userId;
    }

    //不喜欢
    @Override
    public Boolean notLikeUser(Long userId, Long likeUserId) {
        if (this.isNotLike(userId, likeUserId)) {
            return false;
        }
        //不在redis里,没有记录,添加记录到不喜欢的redis中
        String notLikeRedisKey=this.getUserNotLikeRedisKey(userId);
        String hashKey=Convert.toStr(likeUserId);
        this.redisTemplate.opsForHash().put(notLikeRedisKey,hashKey,"1");
        //判断不喜欢的用户是不是在喜欢的列表中,如果在则删除,并删除mongodb中的数据
        if (this.isLike(userId, likeUserId)) {
            //删除MongoDB数据
            Query query=Query.query(Criteria.where("userId").is(userId)
            .and("likeUserId").is(likeUserId));
            this.mongoTemplate.remove(query,UserLike.class);

            //删除redis数据
            String likeRedisKey=this.getUserLikeKey(userId);
            this.redisTemplate.opsForHash().delete(likeRedisKey,hashKey);
        }
        return true;
    }

    @Override
    public Boolean isMutualLike(Long userId, Long likeUserId) {
        if (isLike(userId, likeUserId)) {
            if (isLike(likeUserId,userId)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public List<Long> queryLikeList(Long userId) {
        //mongodb中取
        /*Query query=Query.query(Criteria.where("userId").is(userId))
                .with(Sort.by(Sort.Order.desc("created")));
        List<UserLike> userLikes = this.mongoTemplate.find(query, UserLike.class);
        if (CollUtil.isEmpty(userLikes)) {
            return ListUtil.empty();
        }
        List<Object> likeUserIds = CollUtil.getFieldValues(userLikes, "likeUserId");*/
        //redis取
        String likeRedisKey=this.getUserLikeKey(userId);
        Set<Object> keys = this.redisTemplate.opsForHash().keys(likeRedisKey);
        if (CollUtil.isEmpty(keys)) {
            return ListUtil.empty();//返回空集合
        }
        List<Long> likeUserList=new ArrayList<>(keys.size());
        keys.forEach(o -> likeUserList.add(Convert.toLong(o)));
        return likeUserList;
    }

    @Override
    public List<Long> queryNotLikeList(Long userId) {
        String notLikeRedisKey=this.getUserNotLikeRedisKey(userId);
        Set<Object> keys = this.redisTemplate.opsForHash().keys(notLikeRedisKey);
        if (CollUtil.isEmpty(keys)) {
            return ListUtil.empty();//返回空集合
        }
        List<Long> notLikeUserList=new ArrayList<>(keys.size());
        keys.forEach(o -> notLikeUserList.add(Convert.toLong(o)));
        return notLikeUserList;
    }

    @Override
    public boolean isLike(Long userId, Long likeUserId) {
        String likeRedisKey=this.getUserLikeKey(userId);
        String hashKey=Convert.toStr(likeUserId);

        return this.redisTemplate.opsForHash().hasKey(likeRedisKey,hashKey);
    }

    @Override
    public boolean isNotLike(Long userId, Long likeUserId) {
        String notLikeRedisKey=this.getUserNotLikeRedisKey(userId);
        String hashKey=Convert.toStr(likeUserId);

        return this.redisTemplate.opsForHash().hasKey(notLikeRedisKey,hashKey);
    }
    /**
     * 查询相互喜欢数
     * 实现2种方式：第一种：查询redis，第二种：查询MongoDB
     * 建议：优先使用redis查询，其次考虑使用Mongodb
     *
     * @param userId
     * @return
     */
    @Override
    public Long queryMutualLikeCount(Long userId) {
        //用redis查询
       /* String likeRedisKey=this.getUserLikeKey(userId);
        Set<Object> keys = this.redisTemplate.opsForHash().keys(likeRedisKey);
        Long count=0L;//相互喜欢的数量
        if (CollUtil.isNotEmpty(keys)){
            //不为空查询是否对方也有喜欢用户
            String hashKey=Convert.toStr(userId);
            for (Object key : keys) {
                String redisKey=this.getUserLikeKey(Convert.toLong(key));
                if (this.redisTemplate.opsForHash().hasKey(redisKey,hashKey)) {
                    count++;
                }
            }
        }
        return count;*/
        //由于主动添加的数据过少,所有redis中存的数据不完整,用MongoDB查询
        Query query=Query.query(Criteria.where("userId").is(userId));
       List<UserLike> userLikes = this.mongoTemplate.find(query, UserLike.class);
        if (CollUtil.isEmpty(userLikes)) {
            return null;
        }

        //获取喜欢用户的id
        List<Object> likeUserIds = CollUtil.getFieldValues(userLikes, "likeUserId");
        //定义相互喜欢的数量
        Long count=0L;
        for (Object likeUserId : likeUserIds) {

            Query hasQuery=Query.query(Criteria.where("userId").is(likeUserId)
            .and("likeUserId").is(userId));
            if (this.mongoTemplate.count(hasQuery, UserLike.class)>0) {
                count++;
            }
        }
        return count;
    }

    @Override
    public Long queryLikeCount(Long userId) {
        Query query=Query.query(Criteria.where("userId").is(userId));
        return this.mongoTemplate.count(query,UserLike.class);
    }

    @Override
    public Long queryFanCount(Long userId) {
        Query query=Query.query(Criteria.where("likeUserId").is(userId));
        return this.mongoTemplate.count(query,UserLike.class);
    }

    @Override
    public PageInfo<UserLike> queryMutualLikeList(Long userId, Integer page, Integer pageSize) {


        Query queryLike=Query.query(Criteria.where("userId").is(userId));
        List<UserLike> userLikes = this.mongoTemplate.find(queryLike, UserLike.class);

        List<Object> userLikeList = CollUtil.getFieldValues(userLikes, "likeUserId");
        Query query=Query.query(Criteria.where("userId").in(userLikeList)
        .and("likeUserId").is(userId));

        return this.queryList(query,page,pageSize);
    }



    @Override
    public PageInfo<UserLike> queryLikeList(Long userId, Integer page, Integer pageSize) {
        Query query=Query.query(Criteria.where("userId").is(userId));
        return this.queryList(query,page,pageSize);
    }

    @Override
    public PageInfo<UserLike> queryFanList(Long userId, Integer page, Integer pageSize) {
        Query query=Query.query(Criteria.where("likeUserId").is(userId));
        return this.queryList(query,page,pageSize);
    }
    private PageInfo<UserLike> queryList(Query query, Integer page, Integer pageSize) {
        PageInfo<UserLike> pageInfo=new PageInfo<>();
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pageSize);

        Pageable pageable= PageRequest.of(page-1,pageSize, Sort.by(Sort.Order.desc("created")));
        query.with(pageable);
        List<UserLike> userLikes = this.mongoTemplate.find(query, UserLike.class);
        if (CollUtil.isEmpty(userLikes)){
            log.error("查询的喜欢列表为空");
            return pageInfo;
        }
        pageInfo.setRecords(userLikes);
        return pageInfo;
    }

}
